在 Yii 中使用表單的主要方式是透過 yii\widgets\ActiveForm。當表單基於模型時,應優先選擇此方法。此外,yii\helpers\Html 中有一些有用的方法,通常用於為任何表單新增按鈕和輔助文字。
在客戶端顯示的表單,在大多數情況下都會有一個對應的模型,用於在伺服器端驗證其輸入(有關驗證的更多詳細資訊,請查看驗證輸入章節)。當建立基於模型的表單時,第一步是定義模型本身。該模型可以基於 Active Record 類別(代表來自資料庫的一些資料),或者通用的 Model 類別(從 yii\base\Model 擴展而來)來捕獲任意輸入,例如登入表單。
提示:如果表單欄位與資料庫欄位不同,或者存在僅適用於該表單的格式設定和邏輯,則最好建立一個從 yii\base\Model 擴展而來的獨立模型。
在以下範例中,我們展示了如何將通用模型用於登入表單
<?php
class LoginForm extends \yii\base\Model
{
public $username;
public $password;
public function rules()
{
return [
// define validation rules here
];
}
}
在控制器中,我們將把該模型的實例傳遞給視圖,其中 ActiveForm 小部件用於顯示表單
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$form = ActiveForm::begin([
'id' => 'login-form',
'options' => ['class' => 'form-horizontal'],
]) ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<div class="form-group">
<div class="col-lg-offset-1 col-lg-11">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end() ?>
begin()
和 end()
包裝 ¶在上面的程式碼中,ActiveForm::begin() 不僅建立了一個表單實例,還標記了表單的開始。放置在 ActiveForm::begin() 和 ActiveForm::end() 之間的所有內容都將被包裹在 HTML <form>
標籤中。與任何小部件一樣,您可以透過將陣列傳遞給 begin
方法來指定一些選項,以設定小部件的組態。在本例中,傳遞了一個額外的 CSS 類別和識別 ID,用於開頭的 <form>
標籤。對於所有可用的選項,請參閱 yii\widgets\ActiveForm 的 API 文件。
為了在表單中建立表單元素,以及元素的標籤和任何適用的 JavaScript 驗證,呼叫了 ActiveForm::field() 方法,該方法返回 yii\widgets\ActiveField 的實例。當直接回顯此方法的結果時,結果是一個常規(文字)輸入。若要自訂輸出,您可以將 ActiveField 的其他方法鏈接到此呼叫
// a password input
<?= $form->field($model, 'password')->passwordInput() ?>
// adding a hint and a customized label
<?= $form->field($model, 'username')->textInput()->hint('Please enter your name')->label('Name') ?>
// creating a HTML5 email input element
<?= $form->field($model, 'email')->input('email') ?>
這將根據表單欄位定義的 樣板 建立所有 <label>
、<input>
和其他標籤。輸入欄位的名稱是根據模型的 表單名稱 和屬性名稱自動確定的。例如,上述範例中 username
屬性的輸入欄位名稱將為 LoginForm[username]
。此命名規則將導致伺服器端 $_POST['LoginForm']
中提供登入表單的所有屬性陣列。
提示:如果表單中只有一個模型,並且想要簡化輸入名稱,您可以透過覆寫模型的 formName() 方法以返回空字串來跳過陣列部分。這對於 GridView 中使用的篩選器模型以建立更友好的 URL 很有用。
指定模型的屬性可以透過更複雜的方式完成。例如,當屬性在上傳多個檔案或選擇多個項目時可以採用陣列值時,您可以透過在屬性名稱後附加 []
來指定它
// allow multiple files to be uploaded:
echo $form->field($model, 'uploadFile[]')->fileInput(['multiple'=>'multiple']);
// allow multiple items to be checked:
echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C']);
在命名表單元素(例如送出按鈕)時要小心。根據 jQuery 文件,有些保留名稱可能會導致衝突
表單及其子元素不應使用與表單屬性(例如
submit
、length
或method
)衝突的輸入名稱或 ID。名稱衝突可能會導致令人困惑的失敗。有關規則的完整列表以及檢查您的標記是否存在這些問題,請參閱 DOMLint。
可以使用純 HTML 或使用 Html 輔助工具類別中的方法將其他 HTML 標籤新增到表單中,就像上面的範例中使用 Html::submitButton() 所做的那樣。
提示:如果您在應用程式中使用 Twitter Bootstrap CSS,您可能想要使用 yii\bootstrap\ActiveForm 而不是 yii\widgets\ActiveForm。前者從後者擴展而來,並在產生表單輸入欄位時使用 Bootstrap 特定的樣式。
提示:為了使用星號設定必填欄位的樣式,您可以使用以下 CSS
div.required label.control-label:after { content: " *"; color: red; }
有 3 種清單類型
若要建立清單,您必須準備項目。這可以手動完成
$items = [
1 => 'item 1',
2 => 'item 2'
]
或從資料庫檢索
$items = Category::find()
->select(['label'])
->indexBy('id')
->column();
這些 $items
必須由不同的清單小部件處理。表單欄位的值(和當前活動項目)將由 $model
屬性的當前值自動設定。
我們可以使用 ActiveField yii\widgets\ActiveField::dropDownList() 方法來建立下拉式選單
/* @var $form yii\widgets\ActiveForm */
echo $form->field($model, 'category')->dropdownList([
1 => 'item 1',
2 => 'item 2'
],
['prompt'=>'Select Category']
);
我們可以使用 ActiveField yii\widgets\ActiveField::radioList() 方法來建立單選清單
/* @var $form yii\widgets\ActiveForm */
echo $form->field($model, 'category')->radioList([
1 => 'radio 1',
2 => 'radio 2'
]);
我們可以使用 ActiveField yii\widgets\ActiveField::checkboxList() 方法來建立複選清單
/* @var $form yii\widgets\ActiveForm */
echo $form->field($model, 'category')->checkboxList([
1 => 'checkbox 1',
2 => 'checkbox 2'
]);
Pjax 小部件允許您更新頁面的特定部分,而不是重新載入整個頁面。您可以使用它僅更新表單並在提交後替換其內容。
您可以設定 $formSelector 以指定哪些表單提交可能會觸發 pjax。如果未設定,則 Pjax 封閉內容內的所有具有 data-pjax
屬性的表單都將觸發 pjax 請求。
use yii\widgets\Pjax;
use yii\widgets\ActiveForm;
Pjax::begin([
// Pjax options
]);
$form = ActiveForm::begin([
'options' => ['data' => ['pjax' => true]],
// more ActiveForm options
]);
// ActiveForm content
ActiveForm::end();
Pjax::end();
提示:請小心 Pjax 小部件內的連結,因為回應也將在小部件內呈現。為了避免這種情況,請使用
data-pjax="0"
HTML 屬性。
在使用 jQuery.serializeArray()
處理 檔案 和 送出按鈕值 時,存在已知問題,這些問題將不會解決,而是被 HTML5 中引入的 FormData
類別取代。
這表示使用 ajax 或使用 Pjax 小部件對檔案和送出按鈕值的唯一官方支援取決於 FormData
類別的 瀏覽器支援。
下一節 驗證輸入 處理在伺服器端驗證提交的表單資料,以及 ajax 和客戶端驗證。
若要閱讀有關表單更複雜的用法,您可能需要查看以下章節
發現錯字或您認為此頁面需要改進?
在 github 上編輯 !
註冊 或 登入 以發表評論。